package com.rainkaze.lifeharbor.tools.weather;

import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.rainkaze.lifeharbor.R;
import com.rainkaze.lifeharbor.databinding.ActivityToolWeatherBinding; // 导入生成的绑定类
import com.rainkaze.lifeharbor.tools.weather.adapter.DailyForecastAdapter;
import com.rainkaze.lifeharbor.tools.weather.adapter.HourlyForecastAdapter;
import com.rainkaze.lifeharbor.tools.weather.model.AqiInfo;
import com.rainkaze.lifeharbor.tools.weather.model.CityInfo;
import com.rainkaze.lifeharbor.tools.weather.model.CurrentWeather;
import com.rainkaze.lifeharbor.tools.weather.model.DailyTemperatureValue;
import com.rainkaze.lifeharbor.tools.weather.model.DailyWeatherValue;
import com.rainkaze.lifeharbor.tools.weather.model.ForecastDaily;
import com.rainkaze.lifeharbor.tools.weather.model.ForecastHourly;
// import com.rainkaze.lifeharbor.tools.weather.model.HourlyTemperature; // 未直接使用
// import com.rainkaze.lifeharbor.tools.weather.model.HourlyWeather; // 未直接使用
// import com.rainkaze.lifeharbor.tools.weather.model.HourlyWindItem; // 未直接使用
import com.rainkaze.lifeharbor.tools.weather.model.SunRiseSetValue;
import com.rainkaze.lifeharbor.tools.weather.model.WeatherResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
// import java.util.Calendar; // 未直接使用
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
// import java.util.TimeZone; // 未直接使用

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody; // 导入 ResponseBody

public class WeatherActivity extends AppCompatActivity {

    private static final String TAG = "WeatherActivity";
    private ActivityToolWeatherBinding binding;
    private HourlyForecastAdapter hourlyAdapter;
    private List<HourlyForecastAdapter.HourlyForecastItem> hourlyForecastItemsList;
    private DailyForecastAdapter dailyAdapter;
    private List<DailyForecastAdapter.DailyForecastItem> dailyForecastItemsList;
    private final OkHttpClient client = new OkHttpClient();
    private final Gson gson = new Gson();
    private List<CityInfo> cityList;
    private Map<String, Long> cityNameToIdMap = new HashMap<>();
    private CityInfo selectedCity = null;
    // API 密钥信息
    private static final String API_APP_KEY = "weather20151024";
    private static final String API_SIGN = "zUFJoAR2ZVrDy1vF3D07";
    private static final String API_BASE_URL = "https://weatherapi.market.xiaomi.com/wtr-v3/weather/all";
    private static final int MAXDAILYFORECASTCOUNT = 10;
    // 天气代码到描述和图标的映射
    private static final Map<String, String> weatherCodeToDescriptionMap = new HashMap<>();
    private static final Map<String, Integer> weatherCodeToIconMap = new HashMap<>();

    static {
        // 初始化天气代码映射
        weatherCodeToDescriptionMap.put("0", "晴");
        weatherCodeToDescriptionMap.put("1", "多云");
        weatherCodeToDescriptionMap.put("2", "阴");
        weatherCodeToDescriptionMap.put("3", "阵雨");
        weatherCodeToDescriptionMap.put("4", "雷阵雨");
        weatherCodeToDescriptionMap.put("5", "雷阵雨伴冰雹");
        weatherCodeToDescriptionMap.put("6", "雨夹雪");
        weatherCodeToDescriptionMap.put("7", "小雨");
        weatherCodeToDescriptionMap.put("8", "中雨");
        weatherCodeToDescriptionMap.put("9", "大雨");
        weatherCodeToDescriptionMap.put("10", "暴雨");
        weatherCodeToDescriptionMap.put("11", "大暴雨");
        weatherCodeToDescriptionMap.put("12", "特大暴雨");
        weatherCodeToDescriptionMap.put("13", "阵雪");
        weatherCodeToDescriptionMap.put("14", "小雪");
        weatherCodeToDescriptionMap.put("15", "中雪");
        weatherCodeToDescriptionMap.put("16", "大雪");
        weatherCodeToDescriptionMap.put("17", "暴雪");
        weatherCodeToDescriptionMap.put("18", "雾");
        weatherCodeToDescriptionMap.put("19", "冻雨");
        weatherCodeToDescriptionMap.put("20", "沙尘暴");
        weatherCodeToDescriptionMap.put("21", "小到中雨");
        weatherCodeToDescriptionMap.put("22", "中到大雨");
        weatherCodeToDescriptionMap.put("23", "大到暴雨");
        weatherCodeToDescriptionMap.put("24", "暴雨到大暴雨");
        weatherCodeToDescriptionMap.put("25", "大暴雨到特大暴雨");
        weatherCodeToDescriptionMap.put("26", "小到中雪");
        weatherCodeToDescriptionMap.put("27", "中到大雪");
        weatherCodeToDescriptionMap.put("28", "大到暴雪");
        weatherCodeToDescriptionMap.put("29", "浮尘");
        weatherCodeToDescriptionMap.put("30", "扬沙");
        weatherCodeToDescriptionMap.put("31", "强沙尘暴");
        weatherCodeToDescriptionMap.put("32", "霾");
        weatherCodeToDescriptionMap.put("53", "霾");

        // 天气图标映射
        weatherCodeToIconMap.put("0", R.drawable.sun); // 晴
        weatherCodeToIconMap.put("1", R.drawable.cloudy); // 多云
        weatherCodeToIconMap.put("2", R.drawable.overcast); // 阴
        weatherCodeToIconMap.put("3", R.drawable.rain); // 阵雨
        weatherCodeToIconMap.put("4", R.drawable.rain); // 雷阵雨
         weatherCodeToIconMap.put("5", R.drawable.rain); // 雷阵雨伴冰雹
         weatherCodeToIconMap.put("6", R.drawable.rain); // 雨夹雪
        weatherCodeToIconMap.put("7", R.drawable.rain); // 小雨
        weatherCodeToIconMap.put("8", R.drawable.rain); // 中雨
        weatherCodeToIconMap.put("13", R.drawable.snow); // 阵雪
        weatherCodeToIconMap.put("14", R.drawable.snow); // 小雪
        weatherCodeToIconMap.put("18", R.drawable.fog);   // 雾
        weatherCodeToIconMap.put("32", R.drawable.haze);  // 霾
        weatherCodeToIconMap.put("53", R.drawable.haze);  // 霾
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityToolWeatherBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setupToolbar();
        setInitialViewStates();
        setupRecyclerViews();
        loadCityIds();
        setupCityAutoComplete();

        binding.buttonFetchWeather.setOnClickListener(v -> {
            if (selectedCity != null) {
                fetchWeatherData(selectedCity);
            } else {
                Toast.makeText(this, "请先选择一个城市", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void setupToolbar() {
        setSupportActionBar(binding.toolbarWeather);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        }
    }

    /**
     * 设置视图的初始可见性状态
     */
    private void setInitialViewStates() {
        binding.cardCurrentWeather.setVisibility(View.GONE);
        binding.cardAqi.setVisibility(View.GONE);
        binding.cardTodayForecast.setVisibility(View.GONE);
        binding.recyclerViewHourlyForecast.setVisibility(View.GONE);
        binding.recyclerViewDailyForecast.setVisibility(View.GONE);
        binding.buttonFetchWeather.setVisibility(View.GONE);
        binding.progressBarWeather.setVisibility(View.GONE);
    }

    private void setupRecyclerViews() {
        // 初始化小时预报
        hourlyForecastItemsList = new ArrayList<>();
        hourlyAdapter = new HourlyForecastAdapter(this, hourlyForecastItemsList, weatherCodeToDescriptionMap, weatherCodeToIconMap);
        binding.recyclerViewHourlyForecast.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        binding.recyclerViewHourlyForecast.setAdapter(hourlyAdapter);

        // 初始化每日预报
        dailyForecastItemsList = new ArrayList<>();
        dailyAdapter = new DailyForecastAdapter(this, dailyForecastItemsList, weatherCodeToDescriptionMap, weatherCodeToIconMap, "°C"); // 默认单位
        binding.recyclerViewDailyForecast.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        binding.recyclerViewDailyForecast.setAdapter(dailyAdapter);
    }


    private void loadCityIds() {
        try (InputStream is = getAssets().open("cityIds.json");
             InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
            Type listType = new TypeToken<ArrayList<CityInfo>>() {}.getType();
            cityList = gson.fromJson(reader, listType);
            if (cityList != null) {
                for (CityInfo city : cityList) {
                    cityNameToIdMap.put(city.getCountyname().toLowerCase(Locale.getDefault()), city.getAreaid());
                }
                Log.d(TAG, "已加载 " + cityList.size() + " 个城市数据。");
            } else {
                cityList = new ArrayList<>();
                Log.e(TAG, "从 cityIds.json 加载城市列表失败，结果为 null。");
            }
        } catch (IOException e) {
            Log.e(TAG, "加载 cityIds.json 出错", e);
            Toast.makeText(this, "无法加载城市列表", Toast.LENGTH_LONG).show();
            cityList = new ArrayList<>();
        }
    }

    private void setupCityAutoComplete() {
        if (cityList == null || cityList.isEmpty()) {
            Toast.makeText(this, "城市列表为空，无法设置自动完成。", Toast.LENGTH_SHORT).show();
            return;
        }
        List<String> cityNames = new ArrayList<>();
        for (CityInfo city : cityList) {
            cityNames.add(city.getCountyname());
        }
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
                android.R.layout.simple_dropdown_item_1line, cityNames);
        binding.autoCompleteTextViewCity.setAdapter(adapter);
        binding.autoCompleteTextViewCity.setOnItemClickListener((parent, view, position, id) -> {
            String selectedName = (String) parent.getItemAtPosition(position);
            CityInfo city = findCityInfoByName(selectedName);
            if (city != null) {
                selectedCity = city;
                Log.d(TAG, "城市已选择: " + selectedName + ", ID: " + city.getAreaid());
                binding.buttonFetchWeather.setVisibility(View.VISIBLE);
                fetchWeatherData(selectedCity);
            } else {
                selectedCity = null;
                binding.buttonFetchWeather.setVisibility(View.GONE);
            }
            binding.autoCompleteTextViewCity.clearFocus();
        });
        binding.autoCompleteTextViewCity.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_SEARCH) {
                String inputName = binding.autoCompleteTextViewCity.getText().toString().trim();
                CityInfo foundCity = findCityInfoByName(inputName);
                if (foundCity != null) {
                    selectedCity = foundCity;
                    binding.autoCompleteTextViewCity.setText(foundCity.getCountyname());
                    binding.autoCompleteTextViewCity.dismissDropDown();
                    binding.buttonFetchWeather.setVisibility(View.VISIBLE);
                    fetchWeatherData(selectedCity);
                } else {
                    Toast.makeText(WeatherActivity.this, "未找到城市: " + inputName, Toast.LENGTH_SHORT).show();
                    selectedCity = null;
                    binding.buttonFetchWeather.setVisibility(View.GONE);
                }
                return true;
            }
            return false;
        });
    }

    private CityInfo findCityInfoByName(String name) {
        if (cityList == null || TextUtils.isEmpty(name)) return null;
        String trimmedName = name.trim();
        for (CityInfo city : cityList) {
            // 完全匹配
            if (city.getCountyname().equalsIgnoreCase(trimmedName)) {
                return city;
            }
        }
        return null;
    }

    private void fetchWeatherData(CityInfo city) {
        if (city == null) {
            Toast.makeText(this, "城市信息为空，无法获取天气。", Toast.LENGTH_SHORT).show();
            return;
        }
        String locationKey = "weathercn:" + city.getAreaid();
        runOnUiThread(() -> {
            if (binding == null) return;
            binding.progressBarWeather.setVisibility(View.VISIBLE);
            binding.cardCurrentWeather.setVisibility(View.GONE);
            binding.cardAqi.setVisibility(View.GONE);
            binding.cardTodayForecast.setVisibility(View.GONE);
            binding.recyclerViewHourlyForecast.setVisibility(View.GONE);
            binding.recyclerViewDailyForecast.setVisibility(View.GONE);
            binding.textViewSelectedCity.setText(city.getCountyname());
        });

        HttpUrl.Builder urlBuilder = HttpUrl.parse(API_BASE_URL).newBuilder();
        urlBuilder.addQueryParameter("latitude", "0");
        urlBuilder.addQueryParameter("longitude", "0");
        urlBuilder.addQueryParameter("locationKey", locationKey);
        urlBuilder.addQueryParameter("appKey", API_APP_KEY);
        urlBuilder.addQueryParameter("sign", API_SIGN);
        urlBuilder.addQueryParameter("isGlobal", "false");
        urlBuilder.addQueryParameter("locale", "zh_cn");
        String url = urlBuilder.build().toString();
        Log.d(TAG, "天气 API 请求 URL: " + url);
        Request request = new Request.Builder().url(url).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Log.e(TAG, "获取天气数据失败 (onFailure)", e);
                runOnUiThread(() -> {
                    if (binding == null) return;
                    binding.progressBarWeather.setVisibility(View.GONE);
                    Toast.makeText(WeatherActivity.this, "获取天气数据失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
                });
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                final String responseData;
                try (ResponseBody body = response.body()) {
                    if (body == null) {
                        Log.e(TAG, "天气 API 响应体为空");
                        runOnUiThread(() -> {
                            if (binding == null) return;
                            binding.progressBarWeather.setVisibility(View.GONE);
                            Toast.makeText(WeatherActivity.this, "获取天气数据失败: 响应为空", Toast.LENGTH_LONG).show();
                        });
                        return;
                    }
                    responseData = body.string();
                }

                Log.d(TAG, "天气 API 原始返回数据 (部分): " + (responseData.length() > 1000 ? responseData.substring(0, 1000) + "..." : responseData));

                runOnUiThread(() -> {
                    if (binding == null) return;
                    binding.progressBarWeather.setVisibility(View.GONE);
                    if (response.isSuccessful()) {
                        try {
                            WeatherResponse weatherResponse = gson.fromJson(responseData, WeatherResponse.class);
                            if (weatherResponse != null && weatherResponse.current != null) {
                                updateUi(weatherResponse, city.getCountyname());
                            } else {
                                Log.e(TAG, "解析后的天气数据不完整或为 null");
                                Toast.makeText(WeatherActivity.this, "天气数据格式错误或不完整", Toast.LENGTH_LONG).show();
                            }
                        } catch (Exception e) {
                            Log.e(TAG, "JSON 解析错误", e);
                            Toast.makeText(WeatherActivity.this, "解析天气数据失败", Toast.LENGTH_LONG).show();
                        }
                    } else {
                        Log.e(TAG, "天气 API 请求失败或返回数据错误: " + response.code() + " - " + response.message());
                        Toast.makeText(WeatherActivity.this, "获取天气数据出错: " + response.code(), Toast.LENGTH_LONG).show();
                    }
                });
            }
        });
    }

    private void updateUi(WeatherResponse weatherData, String cityName) {
        if (weatherData == null || binding == null) {
            Log.w(TAG, "updateUi 调用时 weatherData 或 binding 为 null");
            return;
        }

        // 显示所有天气信息卡片和列表
        binding.cardCurrentWeather.setVisibility(View.VISIBLE);
        binding.cardAqi.setVisibility(View.VISIBLE);
        binding.cardTodayForecast.setVisibility(View.VISIBLE);
        binding.recyclerViewHourlyForecast.setVisibility(View.VISIBLE);
        binding.recyclerViewDailyForecast.setVisibility(View.VISIBLE);

        binding.textViewSelectedCity.setText(cityName);

        CurrentWeather current = weatherData.current;
        if (current != null) {
            if (current.temperature != null && !TextUtils.isEmpty(current.temperature.value)) {
                binding.textViewTemperature.setText(String.format(Locale.getDefault(), "%s %s", current.temperature.value, current.temperature.unit));
            } else {
                binding.textViewTemperature.setText("N/A");
            }
            if (current.weather != null) {
                binding.textViewWeatherCondition.setText(getWeatherDescription(current.weather));
                binding.imageViewWeatherIcon.setImageResource(getWeatherIconResId(current.weather));
            } else {
                binding.textViewWeatherCondition.setText("N/A");
                binding.imageViewWeatherIcon.setImageResource(getWeatherIconResId(null)); // 默认图标
            }
            binding.textViewFeelsLike.setText(String.format("体感: %s %s",
                    (current.feelsLike != null && !TextUtils.isEmpty(current.feelsLike.value)) ? current.feelsLike.value : "-",
                    (current.feelsLike != null && !TextUtils.isEmpty(current.feelsLike.unit)) ? current.feelsLike.unit : ""));
            binding.textViewHumidity.setText(String.format("湿度: %s %s",
                    (current.humidity != null && !TextUtils.isEmpty(current.humidity.value)) ? current.humidity.value : "-",
                    (current.humidity != null && !TextUtils.isEmpty(current.humidity.unit)) ? current.humidity.unit : ""));
            binding.textViewWind.setText(String.format("风力: %s %s",
                    (current.wind != null && current.wind.speed != null && !TextUtils.isEmpty(current.wind.speed.value)) ? current.wind.speed.value : "-",
                    (current.wind != null && current.wind.speed != null && !TextUtils.isEmpty(current.wind.speed.unit)) ? current.wind.speed.unit : ""));
            binding.textViewPressure.setText(String.format("气压: %s %s",
                    (current.pressure != null && !TextUtils.isEmpty(current.pressure.value)) ? current.pressure.value : "-",
                    (current.pressure != null && !TextUtils.isEmpty(current.pressure.unit)) ? current.pressure.unit : ""));
            binding.textViewUvIndex.setText(String.format("紫外线: %s", !TextUtils.isEmpty(current.uvIndex) ? current.uvIndex : "-"));
            binding.textViewPubTime.setText(String.format("发布: %s", formatPubTime(current.pubTime)));
        } else {
            Log.w(TAG, "CurrentWeather 数据为 null");
        }

        AqiInfo aqi = weatherData.aqi;
        if (aqi != null) {
            binding.textViewAqiValue.setText(String.format("AQI: %s", !TextUtils.isEmpty(aqi.aqi) ? aqi.aqi : "-"));
            binding.textViewAqiSuggest.setText(String.format("建议: %s", cropAqiSuggest(aqi.suggest)));
            binding.textViewAqiPm25.setText(String.format("PM2.5: %s µg/m³", !TextUtils.isEmpty(aqi.pm25) ? aqi.pm25 : "-"));
            binding.textViewAqiPubTime.setText(String.format("发布: %s", formatPubTime(aqi.pubTime)));
        } else {
            Log.w(TAG, "AqiInfo 数据为 null");
        }

        ForecastDaily daily = weatherData.forecastDaily;
        if (daily != null && daily.temperature != null && daily.temperature.value != null && !daily.temperature.value.isEmpty() &&
                daily.weather != null && daily.weather.value != null && !daily.weather.value.isEmpty() &&
                daily.sunRiseSet != null && daily.sunRiseSet.value != null && !daily.sunRiseSet.value.isEmpty()) {

            DailyTemperatureValue todayTemp = daily.temperature.value.get(0);
            binding.textViewTodayTempRange.setText(String.format(Locale.getDefault(),"温度: %s%s / %s%s",
                    todayTemp.to, daily.temperature.unit, todayTemp.from, daily.temperature.unit));

            DailyWeatherValue todayWeather = daily.weather.value.get(0);
            String dayWeatherCode = todayWeather.from;
            String nightWeatherCode = todayWeather.to;
            String desc = getWeatherDescription(dayWeatherCode);
            if (!dayWeatherCode.equals(nightWeatherCode) && !TextUtils.isEmpty(getWeatherDescription(nightWeatherCode))) {
                if (!desc.equals(getWeatherDescription(nightWeatherCode))) {
                    desc += " 转 " + getWeatherDescription(nightWeatherCode);
                }
            }
            binding.textViewTodayWeatherDesc.setText("天气: " + desc);

            SunRiseSetValue todaySun = daily.sunRiseSet.value.get(0);
            binding.textViewTodaySunRiseSet.setText(String.format("日出: %s  日落: %s",
                    formatSunTime(todaySun.from), formatSunTime(todaySun.to)));

            // 更新每日预报列表 Adapter
            List<DailyForecastAdapter.DailyForecastItem> dailyItems = new ArrayList<>();
            SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.CHINA);
            SimpleDateFormat dateFormatter = new SimpleDateFormat("MM/dd", Locale.CHINA);
            SimpleDateFormat dayOfWeekFormatter = new SimpleDateFormat("E", Locale.CHINA);

            int dailyForecastCount = Math.min(daily.temperature.value.size(), daily.weather.value.size());
            dailyForecastCount = Math.min(dailyForecastCount, daily.sunRiseSet.value.size());
            dailyForecastCount = Math.min(dailyForecastCount, MAXDAILYFORECASTCOUNT);

            for (int i = 0; i < dailyForecastCount; i++) {
                try {
                    String dateString = daily.sunRiseSet.value.get(i).from;
                    Date date = dateParser.parse(dateString);

                    String dateDisplay;
                    if (i == 0) {
                        dateDisplay = "今天";
                    } else if (i == 1) {
                        dateDisplay = "明天";
                    } else {
                        dateDisplay = dayOfWeekFormatter.format(date) + "\n" + dateFormatter.format(date);
                    }

                    DailyTemperatureValue tempVal = daily.temperature.value.get(i);
                    DailyWeatherValue weatherVal = daily.weather.value.get(i);

                    String dayDescLoop = getWeatherDescription(weatherVal.from);
                    String nightDescLoop = getWeatherDescription(weatherVal.to);
                    String fullDescLoop = dayDescLoop;
                    if (!weatherVal.from.equals(weatherVal.to) && !TextUtils.isEmpty(nightDescLoop)) {
                        if (!dayDescLoop.equals(nightDescLoop)) {
                            fullDescLoop += " 转 " + nightDescLoop;
                        }
                    }
                    dailyItems.add(new DailyForecastAdapter.DailyForecastItem(
                            dateDisplay,
                            tempVal.from,
                            tempVal.to,
                            fullDescLoop,
                            weatherVal.from
                    ));
                } catch (ParseException | IndexOutOfBoundsException e) {
                    Log.e(TAG, "解析每日预报数据时出错，索引: " + i, e);
                }
            }
            dailyAdapter.updateData(dailyItems, daily.temperature.unit != null ? daily.temperature.unit : "°C");
        } else {
            Log.w(TAG, "ForecastDaily 数据不完整或为 null");
        }

        // 更新逐小时预报列表 Adapter
        ForecastHourly hourly = weatherData.forecastHourly;
        if (hourly != null && hourly.temperature != null && hourly.temperature.value != null &&
                hourly.weather != null && hourly.weather.value != null &&
                hourly.wind != null && hourly.wind.value != null) {

            List<HourlyForecastAdapter.HourlyForecastItem> hourlyItems = new ArrayList<>();
            int count = hourly.temperature.value.size();
            count = Math.min(count, hourly.weather.value.size());
            count = Math.min(count, hourly.wind.value.size());
            count = Math.min(count, 24);

            // 小米天气API返回的逐小时预报中的 datetime 格式类似 "2023-10-27T08:00:00.000+08:00"
            SimpleDateFormat timeParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.CHINA);
            SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm", Locale.CHINA);

            for (int i = 0; i < count; i++) {
                try {
                    String dateTimeString = hourly.wind.value.get(i).datetime;
                    Date date = timeParser.parse(dateTimeString);
                    String timeDisplay = timeFormatter.format(date);

                    String temp = String.valueOf(hourly.temperature.value.get(i));
                    String weatherCode = String.valueOf(hourly.weather.value.get(i));
                    String tempUnit = hourly.temperature.unit;

                    hourlyItems.add(new HourlyForecastAdapter.HourlyForecastItem(
                            timeDisplay,
                            temp + (!TextUtils.isEmpty(tempUnit) ? tempUnit : "°"),
                            weatherCode
                    ));
                } catch (ParseException | IndexOutOfBoundsException e){
                    Log.e(TAG, "解析逐小时预报数据时出错，索引: " + i, e);
                }
            }
            hourlyAdapter.updateData(hourlyItems);
        } else {
            Log.w(TAG, "ForecastHourly 数据不完整或为 null");
        }
    }


    /**
     * 根据天气代码获取天气描述
     * @param code 天气代码
     * @return 天气描述字符串
     */
    private String getWeatherDescription(String code) {
        if (code == null) return "未知";
        return weatherCodeToDescriptionMap.getOrDefault(code, "代码 " + code);
    }

    /**
     * 裁剪AQI建议，避免过长
     * @param suggest 原始建议
     * @return 裁剪后的建议
     */
    private String cropAqiSuggest(String suggest) {
        //这里先不进行裁剪
//        if (suggest != null && suggest.length() > 25) {
//            return suggest.substring(0, 25) + "...";
//        }
//        return suggest != null ? suggest : "-";
        return suggest;
    }

    /**
     * 根据天气代码获取对应的天气图标资源ID
     * @param code 天气代码
     * @return 图标资源ID
     */
    private int getWeatherIconResId(String code) {
        if (code == null) return R.drawable.unknwn_weather; // 默认未知天气图标
        return weatherCodeToIconMap.getOrDefault(code, R.drawable.unknwn_weather);
    }

    /**
     * 格式化发布时间字符串
     * @param pubTimeString API返回的时间字符串
     * @return 格式化后的时间字符串 (MM-dd HH:mm)
     */
    private String formatPubTime(String pubTimeString) {
        if (TextUtils.isEmpty(pubTimeString)) return "-";
        try {
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.CHINA);
            Date date = inputFormat.parse(pubTimeString);
            SimpleDateFormat outputFormat = new SimpleDateFormat("MM-dd HH:mm", Locale.CHINA);
            return outputFormat.format(date);
        } catch (ParseException e) {
            Log.e(TAG, "解析发布时间格式错误: " + pubTimeString, e);

            if (pubTimeString.length() > 16) {
                return pubTimeString.substring(5, 16).replace("T", " "); // MM-dd HH:mm
            }
            return pubTimeString;
        }
    }

    /**
     * 格式化日出日落时间字符串
     * @param sunTimeString API返回的时间字符串
     * @return 格式化后的时间字符串 (HH:mm)
     */
    private String formatSunTime(String sunTimeString) {
        if (TextUtils.isEmpty(sunTimeString)) return "-";
        try {
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.CHINA);
            Date date = inputFormat.parse(sunTimeString);
            SimpleDateFormat outputFormat = new SimpleDateFormat("HH:mm", Locale.CHINA);
            return outputFormat.format(date);
        } catch (ParseException e) {
            Log.e(TAG, "解析日出日落时间格式错误: " + sunTimeString, e);
            if (sunTimeString.length() > 16) {
                return sunTimeString.substring(11, 16); // HH:mm
            }
            return sunTimeString;
        }
    }

    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        binding = null;
    }
}
